<template>
  <div>
    <el-dialog
      :title="title"
      :visible.sync="visible"
      width="1200px"
      :close-on-click-modal="false"
      :modal-append-to-body="false"
      :append-to-body="true"
      :destroy-on-close="true"
      :before-close="handleClose"
    >

      <el-steps :active="active" :align-center="true" finish-status="success" simple>
        <el-step title="外联表" @click.native="switchStep(0)" />
        <el-step title="字段配置" @click.native="switchStep(1)" />
        <el-step title="筛选条件" @click.native="switchStep(2)" />
        <el-step title="分组" @click.native="switchStep(3)" />
      </el-steps>
      <div v-if="active ==0" class="step">
        <el-form
          ref="viewEdit"
          :model="viewModel"
          :rules="rules"
          label-width="110px"
        >
          <el-form-item label="主表单" prop="TableId">
            <el-row>
              <el-col :span="12">
                <formInput
                  v-model="viewModel.FormId"
                  placeholder="选择主表单"
                  :form-type="[2]"
                />
              </el-col>
              <el-col :span="6">
                <formTableSelect
                  v-model="viewModel.TableId"
                  :form-id="viewModel.FormId"
                  placeholder="选择表"
                  @change="clear"
                />
              </el-col>
              <el-col :span="6" style="text-align: left;">
                <el-button :disabled="viewModel.TableId == null" type="primary" @click="addForm">添加外联表</el-button>
              </el-col>
            </el-row>
          </el-form-item>
          <el-form-item label="外联表">
            <w-table
              :data="tables"
              size="mini"
              :columns="columns"
              :is-paging="false"
            >
              <template slot="joinType" slot-scope="e">
                <el-select
                  v-model="e.row.JoinType"
                  placeholder="选择外联方式"
                >
                  <el-option label="内链接" :value="0" />
                  <el-option label="左链接" :value="1" />
                  <el-option label="右链接" :value="2" />
                </el-select>
              </template>
              <template slot="joinOn" slot-scope="e">
                <el-row style="line-height: 36px;">
                  <el-col :span="18">
                    {{ e.row.JoinShow ? e.row.JoinShow : '未设定' }}
                  </el-col>
                  <el-col :span="6" style="text-align: right;">
                    <el-button type="primary" :disabled="e.row.TableId == null" icon="el-icon-edit" size="mini" circle @click="editJoin(e.row)" />
                  </el-col>
                </el-row>
              </template>
              <template slot="tableId" slot-scope="e">
                <formTableSelect
                  v-model="e.row.TableId"
                  :form-id="e.row.FormId"
                  placeholder="选择表"
                  :filter="(table)=>filterTable(table,e.row)"
                />
              </template>
              <template slot="action" slot-scope="e">
                <el-button type="danger" size="mini" icon="el-icon-delete" circle @click="drop(e.row)" />
              </template>
            </w-table>
          </el-form-item>
        </el-form>
        <div style="text-align: center; margin-top: 10px;">
          <el-button type="primary" @click="saveForm">保存</el-button>
          <el-button @click="resetView">重置</el-button>
        </div>
      </div>
      <div v-else-if="active == 1" class="step">
        <editSelect :form-id="formId" :limit-form-id="limitFormId" :table-id="limitTableId" :selects.sync="selects" />
        <div style="text-align: center;margin-top: 10px;">
          <el-button type="primary" @click="next">下一步</el-button>
          <el-button type="info" @click="prevStep">上一步</el-button>
        </div>
      </div>
      <div v-else-if="active == 2" class="step">
        <whereFilterEdit ref="whereFilter" :form-id="limitFormId" :table-id="limitTableId" :items="wheres" />
        <div style="text-align: center;margin-top: 10px;">
          <el-button type="primary" @click="save">保存</el-button>
          <el-button type="info" @click="prevStep">上一步</el-button>
        </div>
      </div>
      <div v-else-if="active == 3" class="step">
        <el-form
          label-width="110px"
        >
          <el-form-item label="分组字段">
            <el-select
              v-model="groupBy"
              placeholder="选择分组字段"
              style="width: 100%;"
              :multiple="true"
            >
              <el-option v-for="item in selects" :key="item.Id" :label="item.Label" :value="item.Id" />
            </el-select>
          </el-form-item>
          <el-form-item v-if="groupBy && groupBy.length > 0" label="再次筛选">
            <el-row :gutter="8">
              <el-col :span="5">
                <el-select
                  v-model="having.ColId"
                  placeholder="选择筛选字段"
                  clearable
                  style="width: 100%;"
                >
                  <el-option v-for="item in selects.filter(c=>groupBy.includes(c.Id))" :key="item.Id" :label="item.Label" :value="item.Id" />
                </el-select>
              </el-col>
              <el-col :span="4">
                <enumItem
                  v-model="having.Mode"
                  :dic-key="EnumDic.PageFilterMode"
                  placeholder="匹配类型"
                  sys-head="form"
                />
              </el-col>
              <el-col :span="14">
                <filterValueSet v-model="having.Value" :mode="having.Mode" />
              </el-col>
            </el-row>
          </el-form-item>
          <div style="text-align: center; margin-top: 10px;">
            <el-button type="primary" @click="save">保存</el-button>
            <el-button @click="resetView">重置</el-button>
            <el-button type="info" @click="prevStep">上一步</el-button>
            <el-button @click="handleClose">关闭</el-button>
          </div>
        </el-form>
      </div>
    </el-dialog>
    <formChiose title="选择外联表单" :form-type="[2]" :visible.sync="formVisible" @save="addTable" />
    <editJoinOn
      :form-id="curJoinOn.formId"
      :table-id="curJoinOn.tableId"
      :to-form-id="curJoinOn.toFormId"
      :join-on="curJoinOn.joinOn"
      :to-table-id="curJoinOn.toTableId"
      :visible.sync="joinOnVisible"
      @save="saveJoinOn"
    />
  </div>
</template>

<script>
import formInput from '@/customForm/components/form/formInput.vue'
import formChiose from '@/customForm/components/form/formChiose.vue'
import formTableSelect from '@/customForm/components/form/formTableSelect.vue'
import * as viewApi from '@/customForm/api/formView'
import editJoinOn from './components/editJoinOn.vue'
import editSelect from './components/editSelect.vue'
import { EnumDic } from '@/customForm/config/formConfig'
import filterValueSet from './components/filterValueSet.vue'
import whereFilterEdit from './components/whereFilterEdit.vue'
export default {
  components: {
    editJoinOn,
    formTableSelect,
    formInput,
    formChiose,
    editSelect,
    filterValueSet,
    whereFilterEdit
  },
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    formId: {
      type: String,
      default: null
    }
  },
  data() {
    return {
      EnumDic,
      active: 0,
      viewModel: {},
      title: '编辑视图结构',
      formVisible: false,
      curJoinOn: {},
      joinOnVisible: null,
      tables: [],
      limitFormId: [],
      source: null,
      limitTableId: [],
      wheres: [],
      selects: [],
      having: {},
      groupBy: [],
      isRefresh: false,
      id: 0,
      viewId: null,
      columns: [{
        key: 'FormName',
        title: '表单名',
        align: 'left',
        minWidth: 150
      }, {
        key: 'TableId',
        title: '外联表',
        align: 'left',
        minWidth: 150,
        slotName: 'tableId'
      }, {
        key: 'JoinType',
        title: '外联关系',
        align: 'left',
        minWidth: 150,
        slotName: 'joinType'
      }, {
        key: 'JoinOn',
        title: '外联条件',
        align: 'left',
        minWidth: 400,
        slotName: 'joinOn'
      }, {
        key: 'Action',
        title: '操作',
        align: 'left',
        slotName: 'action'
      }],
      rules: {
        TableId: [
          {
            required: true,
            message: '请选择主表单！',
            trigger: 'blur'
          }
        ]
      }
    }
  },
  watch: {
    visible: {
      handler(val) {
        if (val) {
          this.reset()
        } else {
          this.viewModel = {}
        }
      },
      immediate: true
    }
  },
  mounted() {},
  methods: {
    prevStep() {
      this.switchStep(this.active - 1)
    },
    switchStep(val) {
      if (val !== 0 && this.viewModel.TableId == null) {
        return
      } else if (val > 1 && this.selects.length === 0) {
        return
      }
      this.active = val
      this.$nextTick(() => {
        if (this.active !== 1) {
          this.resetForm(this.source)
        }
      })
    },
    resetView() {
      this.resetForm(this.source)
    },
    clear() {
      this.tables = []
      this.refreshLimit()
    },
    filterTable(table, row) {
      return table.Id !== this.viewModel.TableId && this.tables.findIndex(c => c.id !== row.id && c.TableId === table.Id) === -1
    },
    saveJoinOn(data) {
      const item = this.tables.find(c => c.id === this.curJoinOn.id)
      item.JoinOn = data.item
      item.JoinShow = data.show
      this.tables = this.tables.concat([])
      this.refreshLimit()
    },
    refreshLimit() {
      const tids = this.viewModel.TableId ? [this.viewModel.TableId] : []
      const toFormId = this.viewModel.FormId ? [this.viewModel.FormId] : []
      this.tables.forEach(c => {
        if (c.TableId != null) {
          tids.push(c.TableId)
        }
        if (c.FormId != null && !toFormId.includes(c.FormId)) {
          toFormId.push(c.FormId)
        }
      })
      this.limitFormId = toFormId
      this.limitTableId = tids
    },
    editJoin(row) {
      this.curJoinOn = {
        id: row.id,
        tableId: row.TableId,
        formId: row.FormId,
        toTableId: this.limitTableId.filter(c => c !== row.TableId),
        toFormId: this.limitFormId,
        joinOn: row.JoinOn
      }
      this.joinOnVisible = true
    },
    addForm() {
      this.formVisible = true
    },
    addTable(data) {
      this.id = this.id + 1
      this.tables.push({
        id: this.id,
        FormId: data.formId,
        FormName: data.form.FormName,
        JoinType: 0,
        TableId: null,
        JoinOn: {},
        JoinShow: null
      })
      this.refreshLimit()
    },
    drop(row) {
      this.tables = this.tables.filter(c => c.id !== row.id)
    },
    next() {
      if (this.active !== 3) {
        this.active += 1
      }
    },
    async reset() {
      this.id = 0
      this.active = 0
      const res = await viewApi.Find(this.formId)
      this.source = res
      this.resetForm(res)
    },
    resetForm(res) {
      if (res == null) {
        this.viewId = null
        this.viewModel = {
          FormId: null,
          TableId: null
        }
        this.tables = []
        this.wheres = []
        this.groupBy = []
        this.having = {}
        this.limitFormId = []
        this.limitTableId = []
      } else {
        this.viewId = res.Id
        this.viewModel = {
          FormId: res.ViewTable.FormId,
          TableId: res.ViewTable.TableId
        }
        this.groupBy = res.GroupBy ?? []
        this.having = res.HavingSet ?? {}
        this.wheres = res.WhereList ?? []
        if (res.ViewTable.Join == null) {
          this.tables = []
        } else {
          this.tables = res.ViewTable.Join.map(c => {
            this.id = this.id + 1
            c.id = this.id
            return c
          })
        }
        this.refreshLimit()
      }
    },
    format() {
      let where = this.wheres
      if (this.active === 2) {
        const res = this.$refs.whereFilter.getValue()
        if (res.isError) {
          return null
        }
        where = res.rows
      }
      return {
        ViewTable: {
          FormId: this.viewModel.FormId,
          TableId: this.viewModel.TableId,
          Join: this.tables.map(c => {
            return {
              FormId: c.FormId,
              FormName: c.FormName,
              TableId: c.TableId,
              JoinType: c.JoinType,
              JoinOn: c.JoinOn,
              JoinShow: c.JoinShow
            }
          })
        },
        WhereList: where,
        SelectList: this.selects,
        HavingSet: this.having,
        GroupBy: this.groupBy
      }
    },
    handleClose() {
      this.$emit('update:visible', false)
      this.$emit('close', this.isRefresh)
    },
    async set() {
      const data = this.format()
      if (data == null) {
        return
      }
      const isSet = await viewApi.Set(this.viewId, data)
      if (isSet) {
        this.isRefresh = true
        this.source = data
      }
      this.next()
    },
    async add() {
      const data = this.format()
      if (data == null) {
        return
      }
      data.FormId = this.formId
      const id = await viewApi.Add(data)
      data.Id = id
      this.viewId = id
      this.source = data
      this.isRefresh = true
      this.next()
    },
    saveForm() {
      this.$refs['viewEdit'].validate((valid) => {
        if (valid) {
          if (this.viewId == null) {
            this.add()
          } else {
            this.set()
          }
        } else {
          return false
        }
      })
    },
    save() {
      if (this.viewId == null) {
        this.add()
      } else {
        this.set()
      }
    }
  }
}
</script>

<style lang="css" scoped>
.el-step {
  margin-left: 10px;
  margin-right: 10px;
}
.el-step__title {
  cursor: pointer;
}
.step {
  margin-top: 20px;
}
</style>

<style lang="css">
.el-step__title {
  cursor: pointer;
}
</style>
